home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / external / rpc / rpc_xdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-08  |  9.0 KB  |  315 lines

  1. /* 
  2.  * rpc_xdr.c - 
  3.  * This file contains routines required to perform XDR opts on 
  4.  * the non-standard structures passed used with the IDL rpc service.
  5.  */
  6.  
  7. /*
  8.   Copyright (c) 1996-1997, Research Systems Inc.  All rights reserved.
  9.   This software includes information which is proprietary to and a
  10.   trade secret of Research Systems, Inc.  It is not to be disclosed
  11.   to anyone outside of this organization. Reproduction by any means
  12.   whatsoever is  prohibited without express written permission.
  13.   */
  14.  
  15. static char rcsid[] = "$Id: rpc_xdr.c,v 1.31 1997/01/18 08:23:00 ali Exp $";
  16.  
  17.  
  18. #include "idl_rpc.h"
  19. #include "rpc_xdr.h"
  20.  
  21. /*
  22.  * Determine what array and string functions we should use. If we 
  23.  * are on the server side, use the function available via callable
  24.  * IDL, otherwise use the client side functions.
  25.  */
  26.  
  27. #ifndef IDL_RPC_CLIENT
  28.  
  29. #define    IDL_RPC_MAKE_ARRAY           IDL_MakeTempArray
  30. #define    IDL_RPC_STR_ENSURE           IDL_StrEnsureLength
  31. #define    IDL_RPC_VAR_COPY             IDL_VarCopy
  32. #define    IDL_RPC_GET_TMP              IDL_Gettmp
  33. #else
  34.  
  35. /*
  36.  * Routines available on the client side 
  37.  */
  38.  
  39. #define    IDL_RPC_MAKE_ARRAY           IDL_RPCMakeArray
  40. #define    IDL_RPC_STR_ENSURE           IDL_RPCStrEnsureLength
  41. #define    IDL_RPC_VAR_COPY             IDL_RPCVarCopy
  42. #define    IDL_RPC_GET_TMP              IDL_RPCGettmp
  43. #endif
  44.  
  45. /*
  46.  * Declare the xdr routines.
  47.  *
  48.  ***************************************************
  49.  * IDL_RPC_xdr_mips_double()
  50.  *
  51.  * Declare XDR for doubles on mips machines. This is required because
  52.  * DecStation 3100 and other mips machines trash XDR doubles. This routine
  53.  * uses xdr_long() to output the double properly. This works because the
  54.  * mips uses ieee math, the XDR standard.
  55.  */
  56.  
  57. #if defined(mips) || defined(AUX)
  58. publish bool_t IDL_RPC_xdr_mips_double( XDR *xdrs, double *p)
  59. {
  60. #ifdef ultrix            /* Little Endian */
  61.   return(XDR_LONG(xdrs, ((IDL_LONG *) p) + 1) &&
  62.      XDR_LONG(xdrs, (IDL_LONG *) p));
  63. #else                /* Big endian */
  64.   return(XDR_LONG(xdrs, (IDL_LONG *) p)
  65.      && XDR_LONG(xdrs, ((IDL_LONG *) p + 1)));
  66. #endif
  67. }
  68. #endif
  69.  
  70. /*************************************************************
  71.  *  IDL_RPC_xdr_complex
  72.  *      This routine is used to perform xdr ops on an IDL complex
  73.  */
  74. publish bool_t IDL_RPC_xdr_complex( xdrsp, p )
  75.     XDR         * xdrsp;
  76.     IDL_COMPLEX     * p;
  77. {
  78.     return(XDR_FLOAT(xdrsp, (XDR_FLOAT_TYPE *) &(p->r))
  79.        && XDR_FLOAT(xdrsp, (XDR_FLOAT_TYPE *) &(p->i)));
  80. }
  81. /*************************************************************
  82.  *  IDL_RPC_xdr_dcomplex
  83.  *      This routine is used to perform xdr ops on an IDL double complex
  84.  */
  85. publish bool_t IDL_RPC_xdr_dcomplex(XDR *xdrs, IDL_DCOMPLEX *p)
  86. {
  87.   return(XDR_DOUBLE(xdrs, &(p->r)) && XDR_DOUBLE(xdrs, &(p->i)));
  88. }
  89.  
  90. /*************************************************************
  91.  * IDL_RPC_xdr_string
  92.  *      This routine is used to perform xdr ops on an IDL string struct
  93.  */
  94. publish bool_t IDL_RPC_xdr_string( XDR *xdrs, IDL_STRING *pStr)
  95. {
  96.    bool_t  statust;
  97.    short length = pStr->slen;
  98.  
  99. /*
  100.  * First read/write the length
  101.  */
  102.    if(!xdr_short(xdrs, (short*)&length))
  103.        return FALSE;
  104. /*
  105.  * If we are reading the string, make sure that it is long enough
  106.  */
  107.    if(xdrs->x_op == XDR_DECODE){
  108.       pStr->slen = 0;
  109.       pStr->stype= 0;
  110.       IDL_RPC_STR_ENSURE(pStr, length);
  111.       if(length && pStr->s == NULL)
  112.      return FALSE;        /* had an error */
  113.    }
  114. /*
  115.  * Read/write the string, but only if it is non-null
  116.  */
  117.    
  118.    return(length ? xdr_string(xdrs, &pStr->s, length) : TRUE);
  119. }
  120.  
  121. /*************************************************************
  122.  * IDL_RPC_xdr_array
  123.  *
  124.  *   This function performs xdr ops on an IDL array structure.
  125.  *
  126.  */
  127. static bool_t IDL_RPC_xdr_array(XDR *xdrsp, IDL_VPTR pVar)
  128. {
  129.    xdrproc_t   xdr_data_func;    /* function used for array data */
  130.    char       *pData;        /* pointer to array data area   */
  131.    char       *pDim;        /* pointer to dimension array */
  132.    u_int       dimMax = IDL_MAX_ARRAY_DIM;
  133.    int         status;        /* status flag for xdr ops */
  134.    IDL_ARRAY  *pTmpArr;        /* temporary array struct  */
  135.    IDL_ARRAY   sArr;
  136.    IDL_VPTR   vTmp;
  137. /*
  138.  * If we are ecoding, copy over the data contained in the pTmpArr
  139.  * array field. 
  140.  */
  141.    if(xdrsp->x_op != XDR_DECODE){
  142.      if(pVar->flags & IDL_V_ARR) /* is this an array */
  143.         pTmpArr = pVar->value.arr;
  144.      else
  145.         return FALSE;        /* not an array */
  146.    }else 
  147.      pTmpArr = &sArr;
  148. /*
  149.  * read/write the fields that make up the array descriptor. This includes
  150.  * all except the data section.
  151.  */
  152.    pDim = (char *)pTmpArr->dim;
  153.    status = XDR_LONG(xdrsp, IDL_LONGA(pTmpArr->elt_len)) &&
  154.         XDR_LONG(xdrsp, IDL_LONGA(pTmpArr->arr_len)) &&
  155.         XDR_LONG(xdrsp, IDL_LONGA(pTmpArr->n_elts)) &&
  156.         xdr_u_char(xdrsp, IDL_UCHARA(pTmpArr->n_dim)) &&
  157.         xdr_u_char(xdrsp, IDL_UCHARA(pTmpArr->flags)) &&
  158.         xdr_short(xdrsp, IDL_SHORTA(pTmpArr->file_unit)) &&
  159.         xdr_array(xdrsp, &pDim, &dimMax, (u_int)dimMax,
  160.              sizeof(IDL_LONG), (xdrproc_t)XDR_LONG);
  161.    if( status == 0)
  162.       return FALSE;
  163. /*
  164.  * Determine what xdr function will be required to read/write the data 
  165.  */
  166.    switch( pVar->type ){
  167.    case IDL_TYP_BYTE:       
  168.       xdr_data_func   =  (xdrproc_t)xdr_u_char; 
  169.       break;
  170.    case IDL_TYP_INT:  
  171.       xdr_data_func   =  (xdrproc_t)xdr_short;  
  172.       break;
  173.    case IDL_TYP_LONG:
  174.       xdr_data_func   =  (xdrproc_t)XDR_LONG;
  175.       break;
  176.    case IDL_TYP_FLOAT:
  177.       xdr_data_func   =  (xdrproc_t)XDR_FLOAT;  
  178.       break;
  179.    case IDL_TYP_DOUBLE:   
  180.       xdr_data_func   =  (xdrproc_t)XDR_DOUBLE; 
  181.       break;
  182.    case IDL_TYP_COMPLEX:    
  183.       xdr_data_func   =  (xdrproc_t)IDL_RPC_xdr_complex; 
  184.       break;
  185.    case IDL_TYP_STRING:     
  186.       xdr_data_func   =  (xdrproc_t)IDL_RPC_xdr_string; 
  187.       break;
  188.    case IDL_TYP_DCOMPLEX:   
  189.       xdr_data_func   =  (xdrproc_t)IDL_RPC_xdr_dcomplex; 
  190.       break;
  191.    default:
  192.       return FALSE;        /* An Error Condition */
  193.    }
  194. /*
  195.  * If we are decoding, we will need to get an array of the 
  196.  * desired size and type.
  197.  */
  198.    if(xdrsp->x_op == XDR_DECODE){
  199.       pData = IDL_RPC_MAKE_ARRAY(pVar->type, pTmpArr->n_dim, (IDL_LONG*)pDim, 
  200.                 IDL_BARR_INI_ZERO, &vTmp);
  201.    /*
  202.     * Move this array over to the input variable. Will free up any
  203.     * data that needs to be freed.
  204.     */ 
  205.       IDL_RPC_VAR_COPY(vTmp, pVar);  
  206.                         
  207.     }else 
  208.       pData = (char*)pVar->value.arr->data;
  209. /*
  210.  *  Now to Xdr the data
  211.  */
  212.     return xdr_array(xdrsp, &pData, (u_int*)&pTmpArr->n_elts,
  213.               pTmpArr->n_elts, pTmpArr->elt_len, xdr_data_func);
  214. }
  215. /*************************************************************
  216.  * IDL_RPC_xdr_vptr()
  217.  *
  218.  * Used to perform xdr ops on an IDL_VPTR
  219.  */
  220. bool_t IDL_RPC_xdr_vptr(XDR *xdrs, IDL_VPTR *pVar)
  221. {
  222.   bool_t status;
  223.   IDL_VPTR  ptmpVar;
  224.   UCHAR     flags;
  225.  
  226.   if(xdrs->x_op == XDR_DECODE){
  227.      *pVar = IDL_RPC_GET_TMP();    /* Need a variable */
  228.   }else {
  229.     /* client uses the tmp flags */
  230.      flags = ~IDL_V_DYNAMIC & (~IDL_V_TEMP & (*pVar)->flags);    
  231.   }
  232.   ptmpVar = *pVar;
  233.  
  234.   status = xdr_u_char(xdrs, &ptmpVar->type);
  235.   status = (status && xdr_u_char(xdrs, &flags));
  236.  
  237.   if(xdrs->x_op == XDR_DECODE)
  238.      ptmpVar->flags |= flags;  /* preserve the old flags */
  239.  
  240.   if(status == FALSE)
  241.      return status;
  242. /*
  243.  * Do we have an array?
  244.  */
  245.    if(ptmpVar->flags & IDL_V_ARR)
  246.       return IDL_RPC_xdr_array(xdrs, ptmpVar);
  247. /*
  248.  * Must have a scalar, Determine the type and xdr
  249.  */
  250.    switch(ptmpVar->type){
  251.    case IDL_TYP_UNDEF:
  252.       status = TRUE;
  253.       break;
  254.    case IDL_TYP_BYTE:
  255.       status = xdr_u_char(xdrs, &ptmpVar->value.c);
  256.       break;
  257.    case IDL_TYP_INT:
  258.       status = xdr_short(xdrs, &ptmpVar->value.i);
  259.       break;
  260.    case IDL_TYP_LONG:
  261.       status = XDR_LONG(xdrs, &ptmpVar->value.l);
  262.       break;
  263.    case IDL_TYP_FLOAT:
  264.       status = XDR_FLOAT(xdrs, &ptmpVar->value.f);
  265.       break;
  266.    case IDL_TYP_DOUBLE:
  267.       status = XDR_DOUBLE(xdrs, &ptmpVar->value.d);
  268.       break;
  269.    case IDL_TYP_COMPLEX:
  270.       status = IDL_RPC_xdr_complex(xdrs, &ptmpVar->value.cmp);
  271.       break;
  272.    case IDL_TYP_STRING:
  273.       status = IDL_RPC_xdr_string(xdrs, &ptmpVar->value.str);
  274.    /*
  275.     * Make sure that the dynamic flag is set 
  276.     */
  277.       if(ptmpVar->value.str.stype)
  278.          ptmpVar->flags |= IDL_V_DYNAMIC;
  279.       break;
  280.    case IDL_TYP_DCOMPLEX:
  281.       status = IDL_RPC_xdr_dcomplex(xdrs, &ptmpVar->value.dcmp);
  282.       break;
  283.    default: status = FALSE;
  284.    }
  285.    return status;
  286. }
  287. /*************************************************************
  288.  * IDL_RPC_xdr_variable()
  289.  *
  290.  * Used to perform xdr ops on an RPC variable structure. This 
  291.  * structure contains the variable name and an IDL_VPTR.
  292.  */
  293. bool_t IDL_RPC_xdr_variable(XDR *xdrs, IDL_RPC_VARIABLE *pVar)
  294. {
  295.    unsigned int maxElem = MAXIDLEN +1;
  296.    return(xdr_wrapstring(xdrs, &pVar->name) &&
  297.       IDL_RPC_xdr_vptr(xdrs, &pVar->pVariable));
  298. }
  299. /*************************************************************
  300.  * IDL_RPC_xdr_line_s()
  301.  * 
  302.  * This function is used to perform XDR ops on a structure 
  303.  * of type IDL_RPC_LINE_S. This structure is used to pass 
  304.  * idl output lines between the rpc server and client.
  305.  */
  306.  
  307. bool_t IDL_RPC_xdr_line_s(XDR *xdrs, IDL_RPC_LINE_S *pLine)
  308. {
  309.    return (xdr_int(xdrs, &pLine->flags) &&
  310.         xdr_wrapstring(xdrs, &pLine->buf));
  311. }
  312.   
  313.  
  314.  
  315.